function isFunction(obj) {
  return typeof obj === 'function' && typeof obj.nodeType !== 'number';
}
function isSet(obj) {
  return Object.prototype.toString.call(obj) === '[object Set]';
}
function clone(obj) {
  if (!obj || typeof obj !== 'object') {
    return obj;
  }
  if (isSet(obj)) {
    var newSet = new Set();
    for (var prop of obj) {
      newSet.add(clone(prop));
    }
    return newSet;
  } else if (obj instanceof Array) {
    if (!Array.isArray(obj)) {
      obj = Array.from(obj);
    }
    return obj.map((item) => {
      return clone(item);
    });
  } else if(obj instanceof Date){
    return new Date(obj);
  } else {
    var newObj = {};
    for (var key in obj) {
      newObj[key] = clone(obj[key]);
    }
    return newObj;
  }
}

// const date = new Date();
// const arr = [];
// const o = {};
// const func = function () {
//   console.log('----------');
// };
/**
 * 深拷贝
 * 仅考虑 Array、Object、Set、Function 和基本类型
 */

/**
 * @param {Array|Object|Set|Function|string|number} value
 * @returns {Array|Object|Set|Function|string|number}
 * @example
 * const obj = {
 *   a: 1,
 *   b: 'xxx',
 *   c: new Set([1, 2, 3]),
 *   d: { e: 'eee' },
 *   f: () => {},
 *   g: [1, 2, 3],
 * };
 */
// const obj = {
//   a: 1,
//   b: 'xxx',
//   c: new Set([1, 2, 3]),
//   d: { e: 'eee' },
//   f: () => { console.log('-----f-----')},
//   g: [1, 2, 3],
//   h: new Date()
// };
// const newObj = clone(obj);

// // const newObj = Object.assign({}, obj);
// // console.log(newObj);
// // arr.push(1);
// // o['a'] = 'abc';
// obj.h.setDate(13);
// // console.log(newObj);
// // console.log(typeof obj.c);
// // obj.c.add(4);
// // newObj.c.add(99);
// // newObj.f();
// // obj.f = () => { console.log('-------------old') };
// // newObj.f();
// // console.log(newObj.c)
// // console.log(obj.c)
// console.log(obj.h);
// console.log(newObj.h);


const date = new Date();
const arr = [];
const o = {};
const set = new Set([1, 2]);
const fn = ()=>{console.log('------------before------')};
const obj = {
  date,
  arr,
  o,
  set,
  fn
};
const newObj = clone(obj, true);
arr.push(1);
o['a'] = 'abc';
date.setDate(13);
set.add(3);
obj.fn = ()=>{console.log('------------after------')};
console.log(newObj);
newObj.fn()
